import datetime,math
def record_del(filename):
        name=str(filename)+".txt"
        with open(name,"w") as write_data:
                write_data.write("")
def record(filename,string):
        name=str(filename)+".txt"
        with open(name,"a") as write_data:
                write_data.writelines(str(string)+"\n")


class bug(object):
    """Generic bug handler"""
    def __init__(self,error_type="generic"):
        ##will record to "error_generic.txt" unless error_type is specified
        self.type=error_type
        self.now = datetime.datetime.now()
    def bug_record(self,message,urgency=0):
        filename="Error_"+str(self.type)
        record(filename,"["+str(urgency)+"] "+str(self.now.strftime("%d-%m-%Y AT %H:%M:%S \t \t"))+str(message))
        print "record successful:  recorded to\t",filename+".txt"


class schema_reader(object):

        """class for reading and minipulating schema files"""
        
        from PIL import Image
        #######CAUTION
        ##This class hasn't been proof read - a few of the funcitons may not work
        ## if you get a "global value referenced before whatever" error
        ## its likely caused by the funciton-call not having self. in front of it (to make it a method
        ##during an internal call!
                ##SORRY!

        ##IN the schema files, items are listed as "options" under [sections]: schema > section > option

        ##schema_type cane be "mech", "weapon_root", or "weapon_main"
                ##mechs are obvious: it gives the stats for the mech
                ##weapon_roots are used for generating weapon series
                ##weapon_main are used for individual weapon stats.
        def read_schema(self,name,section="null",option="null",mode=0,schema_type="mech"):
                """Parses a schema and returns an individual value, a list of options, a list of sections or a dictionary of everything"""
                    ##mode 0: get individual value from section/option
                    ##mode 1: return list of options in section
                    ##mode 2: return list of sections in file
                    ##mode 3: return a DICITONARY of ALL key-value pairs
                import ConfigParser
                config=ConfigParser.ConfigParser()
                
                        ##remove .txt extension if applicable
                if name[-4:] ==".txt":
                        name=name[:-4]
                        ##parse schema_type to read the correct file (from the correct directory)
                if schema_type=="mech" or schema_type==0:
                        file_path=str("../Schematics/mech_schematics/"+name+".txt")
                if schema_type=="weapon_root" or schema_type==1:
                        file_path=str("../Schematics/weapon_schematics/weapon_root/"+name+".txt")
                if schema_type=="weapon_main" or schema_type==2:
                        file_path=str("../Schematics/weapon_schematics/weapon_main/"+name+".txt")
                                
                try:
                        config.read(file_path)
                            
                        if mode==0:
                            return eval(config.get(section,option))
                        if mode==1:
                            return config.options(section)
                        if mode==2:
                            return config.sections()
                        if mode==3:
                            return_dict={}
                            for sections in config.sections():
                                    for options in config.options(sections):
                                            
                                            return_dict[options]=eval(config.get(sections,options))
                            return return_dict

                except:
                        debug=bug()
                        string=str((name,section,option))
                        message=str("failed to read schema file: "+string+" please check calls for file: "+file_path)
                        print "error detected:"
                        debug.bug_record(message)
            
        def load_mechlist(self):
                """returns a list of all schema in the mech_schematics folder"""
                import os
                path="../Schematics/mech_schematics/"
                dirlist=os.listdir(path)
                return dirlist

        def load_weplist(self,mode="root"):
                """returns a list of all schema in the weapon_root or _main folder, depending on mode"""
                import os
                if mode in ("root",1):
                        path="../Schematics/weapon_schematics/weapon_root"
                if mode in ("main",0):
                        path="../Schematics/weapon_schematics/weapon_main"
                dirlist=os.listdir(path)
                return dirlist

        def populate_weaponlist_auto(self,scale=1):
                """Parses all available weapon_root files and produces a weapon series for each"""
                parsed=[]
                for list in self.load_weplist("root"):
                       multi = self.read_schema(list,section="scale",option="multi",mode=0,schema_type="weapon_root")
                       
                       if multi==0:
                               self.write_weapon(name=list,wep_size=0,size_scale=1)
                               parsed.append(list+" single")
                       if multi >0:
                               for i in range(1,4):
                                       self.write_weapon(name=list,wep_size=i,size_scale=1)

                                       parsed.append(list+" multi="+str(i))
                return parsed

        def populate_weaponlist_manual(self,rootname="null",scale=1,multi=0):
                """Parse a single weapon_root file and produce weapon series for it"""
                if multi==0:
                        self.write_weapon(name=rootname,wep_size=0,size_scale=1)
                if multi >0:
                        for i in range(1,4):
                                self.write_weapon(name=rootname,wep_size=i,size_scale=1)

        def write_weapon(self,name="null",size_scale=1,wep_size=1):
                """records the statistics for a weapon file"""
                
                ## configparser is used to parse the files
                ## Image class from PIL is used to look for the pixel-origin of the weapon-image

                import ConfigParser
                config=ConfigParser.ConfigParser()

                root_stats=self.read_schema(name,mode=3,schema_type="weapon_root")
                print root_stats
                ####CALCULATE THE INCREMENT BEFORE CALLING config.set TO AVOID CONFUSION
                
                
                config.add_section("core")
                config.add_section("stats")
                config.add_section("effect")
                
                if wep_size==1:
                        size=0.75
                        size_name="L"
                        description=root_stats["description1"]
                        catagory=root_stats["light"]
                elif wep_size==2:
                        size=1.0
                        size_name="M"
                        description=root_stats["description2"]
                        catagory=root_stats["medium"]
                elif wep_size==3:
                        size=1.25
                        size_name="H"
                        description=root_stats["description3"]
                        catagory=root_stats["heavy"]
                else:
                        size=1
                        size_name=""
                        description=root_stats["description"]
                        catagory=root_stats["name"]

                print size,(size*size_scale)
                size_mod=(size*size_scale)
                
                acc_inc=float((root_stats["final_accuracy"]-root_stats["base_accuracy"]))/(root_stats["steps"]-1)*size_mod
                range_inc=float((root_stats["final_range"]-root_stats["base_range"]))/(root_stats["steps"]-1)*(1/size_mod)
                dmg_inc=(root_stats["final_dmg"]-root_stats["base_dmg"])/(root_stats["steps"]-1)*size_mod
                shots_inc=float((root_stats["final_shots"]-root_stats["base_shots"]))/(root_stats["steps"]-1)*(1/size_mod)
                duration_inc=float((root_stats["final_duration"]-root_stats["base_duration"]))/(root_stats["steps"]-1)
                ammo_inc=float((root_stats["final_ammo"]-root_stats["base_ammo"]))/(root_stats["steps"]-1)*(1/size_mod)
                scale_inc=float((root_stats["final_shot_scale"]-root_stats["shot_scale"]))/(root_stats["steps"]-1)*size_mod
                heat_inc=float((root_stats["final_heat"]-root_stats["base_heat"]))/(root_stats["steps"]-1)*size_mod

                        
                for i in range(1,root_stats["steps"]+1):
                        print i
                ##set options for "stats" section
                #config.set(section, option, value)
                        
                        
                        calc_dmg=round((root_stats["base_dmg"]+((i-1)*dmg_inc))*size_mod,-1)
                        calc_range=(root_stats["base_range"]+((i-1)*range_inc))*size_mod
                        calc_ammo=(root_stats["base_ammo"]+((i-1)*ammo_inc))*(1/size_mod)
                        calc_shots=(root_stats["base_shots"]+((i-1)*shots_inc))*(1/size_mod)
                        calc_accuracy=root_stats["base_accuracy"]+((i-1)*acc_inc)*(1/size_mod)
                        calc_heat=root_stats["base_heat"]+((i-1)*heat_inc)*size_mod

                        
                        
                        calc_tier=max(1,math.floor(min(4,
                                                      (calc_dmg/200)
                                                      +(calc_range/10)
                                                      +(calc_ammo/20)
                                                      +(calc_shots/100)
                                                      +(calc_accuracy/30)
                                                      )))
                        
                        #calculate names and filepaths
                        newname=size_name+root_stats["name"].upper()+"-"+str(int(calc_dmg))

                        
############    NOT quite sure what I was thinking here:
                        ##would appear to have been an attempt at adding unique effect-sprites
                                ##but I dont ahve nay need of that: will look into it again at some point
                                        ##but not just now
                ##note the method of having different smoke, projectile, muzzleflash and trail sprites - and
                ##altering the trail length...
                        
####                        sprite_number=max(int(float(root_stats["sprite_steps"]*i)/root_stats["steps"]),1)
####                        sprite_name=catagory+"_"+str(sprite_number)+".png"
####                        sprite_name=catagory+"_"+str(sprite_number)+".png"
####
####                        projetile_number=max(int(float(root_stats["projectile_steps"]*i)/root_stats["steps"]),1)
####                        proj_name=catagory+"_"+str(projetile_number)+".png"
####                        proj_name=str(root_stats["projectile"])+".png"
####                        
####                        muzzle_number=max(int(float(root_stats["muzzle_steps"]*i)/root_stats["steps"]),1)
####                        muz_name=catagory+"_"+str(muzzle_number)+".png"
####                        muz_name=str(root_stats["muzzle"])+".png"
####                        
####                        smoke_number=max(int(float(root_stats["smoke_steps"]*i)/root_stats["steps"]),1)
####                        smoke_name=catagory+"_"+str(sprite_number)+".png"
####                        smoke_name=str(root_stats["smoke"])+".png"
####                        
####                        hit_number=max(int(float(root_stats["hit_steps"]*i)/root_stats["steps"]),1)
####                        hit_name=catagory+"_"+str(hit_number)+".png"
####                        hit_name=str(root_stats["hit"])+".png"
####                        
####                        trail_number=max(int(float(root_stats["trail_steps"]*i)/root_stats["steps"]),1)
####                        trail_name=catagory+"_"+str(trail_number)+".png"
####                        trail_name=str(root_stats["trail"])+".png"

                        sprite_number=max(int(float(root_stats["sprite_steps"]*i)/root_stats["steps"]),1)
                        sprite_name=catagory+"_"+str(sprite_number)+".png"
                        proj_name=str(root_stats["projectile"])+".png"
                        muz_name=str(root_stats["muzzle"])+".png"
                        smoke_name=str(root_stats["smoke"])+".png"
                        hit_name=str(root_stats["hit"])+".png"
                        trail_name=str(root_stats["trail"])+".png"

                        print sprite_name,proj_name,muz_name,smoke_name,hit_name
                        
                        
                        config.set("stats", "tier", int(calc_tier))
                        config.set("stats", "accuracy",int(calc_accuracy))
                        config.set("stats", "range",int(calc_range))
                        config.set("stats", "dmg",int(calc_dmg))
                        config.set("stats", "num_shots",int(calc_shots))
                        config.set("stats", "duration",int(root_stats["base_duration"]+((i-1)*duration_inc)))
                        config.set("stats", "ammo",int(calc_ammo))
                        config.set("stats", "heat",int(calc_heat))

                        mass=((calc_dmg/10)+calc_range+(calc_ammo/10)+(calc_shots/10)+(calc_accuracy/10))*root_stats["mass_mod"]*size_mod
                        cost=round(((calc_dmg/10)+calc_range+(calc_ammo/10)+(calc_shots/10)+(calc_accuracy/10))*root_stats["cost_mod"]*100*calc_tier,-1)


                        config.set("stats", "mass",int(mass))
                        config.set("stats", "cost",int(cost))
                        
                ##set options for "core" section
                        config.set("core","name",newname)
                        config.set("core","type",root_stats["type"])
                        config.set("core","name_long",root_stats["name_long"])
                        config.set("core","description",str(description))

                ##set options for "effects" section
                        #spritename
                        config.set("effect","class",root_stats["name"].lower())
                        
                        config.set("effect","sprite",(sprite_name,self.get_wep_origins(sprite_name,root_stats["name"].lower())))
                        config.set("effect","projectile",proj_name)
                        config.set("effect","muzzle",(muz_name,))
                        config.set("effect","smoke",(smoke_name,))
                        config.set("effect","hit",hit_name)
                        config.set("effect","trail",trail_name)
                        config.set("effect", "shot_scale",round(root_stats["shot_scale"]+((i-1)*scale_inc),3))

                        
                        print newname,"[ TIER:",int(math.ceil(calc_tier)),"] [ MASS:",int(mass),"] [ COST:", int(cost),"]"
                        file_path=str("../Schematics/weapon_schematics/weapon_main/"+newname+".txt")
                        with open(file_path, "w") as configfile:
                                config.write(configfile)

##WHY IS THIS DUPLICATED IN COLOUR.PY!?!?!?!
                        
        def get_pixel(self,r=0,g=0,b=0,a="null",img_path="null",mode=0):
            """Returns a list of all pixels matching the RGB(A) value [only returns first instance of pixel if mode=1]"""
            
            if img_path == "null":
                print "bad img_path"
                return

            texture = self.Image.open(img_path)
            if a != "null":
                texture = texture.convert("RGBA")
                search=r,g,b,a
            else:
                texture = texture.convert("RGB")
                search=r,g,b
                
            pixdata = texture.load()
            return_list=[]
            for y in xrange(texture.size[1]):
                for x in xrange(texture.size[0]):
                    if pixdata[x, y] == search and mode==0:
                        return_list.append((x,y))
                    elif pixdata[x, y] == search and mode==1:
                        return x,y
            return return_list

        def get_wep_origins(self,img_name,wep_class):
                """returns a list of origins from a weapon file"""
                filepath="../Graphics/Sprites/Mecha/Weapon/"+str(wep_class)+"/"+str(img_name)
                origin=self.get_pixel(255,126,0,'null',filepath,1)
                muzzle=self.get_pixel(34,177,76,'null',filepath,1)
                smoke=self.get_pixel(255,163,177,'null',filepath,1)

                if smoke==[]:
                        smoke=muzzle
                return origin,muzzle,smoke
                    
        
                     
                
 ##this will scan through each item in the slots section and can be used to get stats from it
        ##USE this to assemble mecha-pictures
#for list in read_schema("sidnam","slots","2",1):
#	read_schema("sidnam","slots",list)

######USE THIS IN COMBINATION WITH A VARIATION OF THE BACKROUND-TO-ALPHA CODE
######TO GET x,y COORDINATES OF MUZZLE, ORIGIN AND SMOKE-POINT

####added variable sprites to root files: and figured out a method to automatically
####determine origin locations on weapon sprites
####- orange = origin (255,126,0,255 replace with alpha-orange(255,126,0,0))
####- green = muzzle_point (34,177,76,255, replace with black (0,0,0,255))
####- pink = smoke_point (255,163,177,255 replace with black (0,0,0,255))(if not
####found, same as muzzle point - else spawn smoke on fire)






